﻿using Entity = Ruirun.Mes.Entities.MaterialCategory;
using IContractService = Ruirun.Mes.IMesService;
using InputDto = Ruirun.Mes.Dtos.MaterialCategoryInputDto;
using OutputDto = Ruirun.Mes.Dtos.MaterialCategoryOutputDto;

namespace Ruirun.Mes.Api.Areas.Admin.Controllers
{
    [Description("物料")]
    [ModuleInfo(OrderNo = 4, Position = "Wms", PositionName = "仓储模块")]
    public class MaterialCategoryController : AdminControllerBase
    {
        /// <summary>
        /// 获取 服务接口
        /// </summary>
        protected IContractService ContractService => ServiceProvider.GetService<IContractService>();

        /// <summary>
        /// 读取
        /// </summary>
        [HttpPost]
        [Description("读取")]
        [ModuleInfo]
        public PageData<OutputDto> Read(PageRequest request)
        {
            Check.NotNull(request, nameof(request));
            IFunction function = this.GetExecuteFunction();

            Expression<Func<Entity, bool>> predicate = FilterService.GetExpression<Entity>(request.FilterGroup);
            var page = CacheService.ToPageCache<Entity, OutputDto>(ContractService.MaterialCategorys, predicate, request.PageCondition,
               function);

            return page.ToPageData();
        }

        /// <summary>
        /// 新增
        /// </summary>
        [ModuleInfo]
        [Description("新增")]
        [DependOnFunction(nameof(Read))]
        [UnitOfWork]
        [HttpPost]
        public async Task<AjaxResult> Create(InputDto[] dtos)
        {
            Check.NotNull(dtos, nameof(dtos));
            List<string> ids = new();
            List<OutputDto> outputDtos = new();
            foreach (var dto in dtos)
            {
                var entity = dto.MapTo<Entity>();
                var result = await ContractService.CreateMaterialCategory(entity);
                if (!result.Succeeded)
                {
                    return result.ToAjaxResult();
                }
                ids.Add(dto.Id.ToString());
                outputDtos.Add(dto.MapTo<OutputDto>());
            }
            return AjaxResult.Success(outputDtos, $"{nameof(Entity)}“{ids.ExpandAndToString()}”创建成功");
        }

        /// <summary>
        /// 更新
        /// </summary>
        [HttpPost]
        [DependOnFunction(nameof(Read))]
        [UnitOfWork]
        [Description("更新")]
        [ModuleInfo]
        public async Task<AjaxResult> Update(InputDto[] dtos)
        {
            Check.NotNull(dtos, nameof(dtos));
            List<string> ids = new();
            List<OutputDto> outputDtos = new();
            foreach (var dto in dtos)
            {
                var entity = dto.MapTo<Entity>();
                var result = await ContractService.UpdateMaterialCategory(entity);
                if (!result.Succeeded)
                {
                    return result.ToAjaxResult();
                }
                ids.Add(dto.Id.ToString());
                outputDtos.Add(dto.MapTo<OutputDto>());
            }
            return AjaxResult.Success(outputDtos, $"{nameof(Entity)}“{ids.ExpandAndToString()}”更新成功");
        }

        /// <summary>
        /// 删除
        /// </summary>
        [HttpPost]
        [DependOnFunction(nameof(Read))]
        [UnitOfWork]
        [Description("删除")]
        [ModuleInfo]
        public async Task<AjaxResult> Delete(Guid[] ids)
        {
            Check.NotNull(ids, nameof(ids));
            var result = await ContractService.DeleteMaterialCategorys(ids);
            return result.ToAjaxResult();
        }

        /// <summary>
        /// 读取组织机构树
        /// </summary>
        /// <param name="request">分页请求</param>
        /// <returns>组织机构树页列表</returns>
        [HttpPost]
        [ModuleInfo]
        [Description("读取树")]
        public virtual PageData<MaterialCategoryTreeNodeDto> ReadTree(PageRequest request)
        {
            Check.NotNull(request, nameof(request));
            IFunction function = this.GetExecuteFunction();

            request.AddDefaultSortCondition(new SortCondition("TreePathString", ListSortDirection.Ascending));

            Func<MaterialCategory, bool> updateFunc = FilterService.GetDataFilterExpression<MaterialCategory>(null, DataAuthOperation.Update).Compile();
            Func<MaterialCategory, bool> deleteFunc = FilterService.GetDataFilterExpression<MaterialCategory>(null, DataAuthOperation.Delete).Compile();
            Expression<Func<MaterialCategory, bool>> predicate = FilterService.GetExpression<MaterialCategory>(request.FilterGroup);

            PageResult<MaterialCategoryNodeDto> page = CacheService.ToPageCache(ContractService.MaterialCategorys, predicate, request.PageCondition
          , m => m, function).ToPageResult(data => data.Select(m => new MaterialCategoryNodeDto(m)).ToArray());

            var treeNodes = page.Data.ToTreeNodes();
            PageResult<MaterialCategoryTreeNodeDto> treeNodePage = new(treeNodes.ToArray(), page.Total);

            return treeNodePage.ToPageData();
        }


        /// <summary>
        /// 读取树节点
        /// </summary>
        /// <returns>组织机构树页列表</returns>
        [HttpPost]
        [AllowAnonymous]
        [Description("读取树")]
        public AjaxResult GetTreeNodes()
        {
            IFunction function = this.GetExecuteFunction();
            var nodeList = CacheService.ToCacheList(ContractService.MaterialCategorys, m => m.MapTo<MaterialCategory, MaterialCategoryNodeDto>(), function);
            var treeNodes = nodeList.ToTreeNodes();

            return AjaxResult.Success(treeNodes.ToArray());
        }
     
    }
}